//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension SSMContacts {
    // MARK: Enums

    public enum AcceptCodeValidation: String, CustomStringConvertible, Codable, _SotoSendable {
        case enforce = "ENFORCE"
        case ignore = "IGNORE"
        public var description: String { return self.rawValue }
    }

    public enum AcceptType: String, CustomStringConvertible, Codable, _SotoSendable {
        case delivered = "DELIVERED"
        case read = "READ"
        public var description: String { return self.rawValue }
    }

    public enum ActivationStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case activated = "ACTIVATED"
        case notActivated = "NOT_ACTIVATED"
        public var description: String { return self.rawValue }
    }

    public enum ChannelType: String, CustomStringConvertible, Codable, _SotoSendable {
        case email = "EMAIL"
        case sms = "SMS"
        case voice = "VOICE"
        public var description: String { return self.rawValue }
    }

    public enum ContactType: String, CustomStringConvertible, Codable, _SotoSendable {
        case escalation = "ESCALATION"
        case personal = "PERSONAL"
        public var description: String { return self.rawValue }
    }

    public enum ReceiptType: String, CustomStringConvertible, Codable, _SotoSendable {
        case delivered = "DELIVERED"
        case error = "ERROR"
        case read = "READ"
        case sent = "SENT"
        case stop = "STOP"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AcceptPageRequest: AWSEncodableShape {
        /// The accept code is a 6-digit code used to acknowledge the page.
        public let acceptCode: String
        /// An optional field that Incident Manager uses to ENFORCE AcceptCode validation when acknowledging an page. Acknowledgement can occur by replying to a page, or when entering the AcceptCode in the console. Enforcing AcceptCode validation causes Incident Manager to verify that the code entered by the user matches the code sent by Incident Manager with the page. Incident Manager can also IGNORE AcceptCode validation. Ignoring AcceptCode validation causes Incident Manager to accept any value entered for the AcceptCode.
        public let acceptCodeValidation: AcceptCodeValidation?
        /// The type indicates if the page was DELIVERED or READ.
        public let acceptType: AcceptType
        /// The ARN of the contact channel.
        public let contactChannelId: String?
        /// Information provided by the user when the user acknowledges the page.
        public let note: String?
        /// The Amazon Resource Name (ARN) of the engagement to a contact channel.
        public let pageId: String

        public init(acceptCode: String, acceptCodeValidation: AcceptCodeValidation? = nil, acceptType: AcceptType, contactChannelId: String? = nil, note: String? = nil, pageId: String) {
            self.acceptCode = acceptCode
            self.acceptCodeValidation = acceptCodeValidation
            self.acceptType = acceptType
            self.contactChannelId = contactChannelId
            self.note = note
            self.pageId = pageId
        }

        public func validate(name: String) throws {
            try self.validate(self.acceptCode, name: "acceptCode", parent: name, max: 10)
            try self.validate(self.acceptCode, name: "acceptCode", parent: name, min: 6)
            try self.validate(self.acceptCode, name: "acceptCode", parent: name, pattern: "^[0-9]*$")
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.note, name: "note", parent: name, max: 2048)
            try self.validate(self.note, name: "note", parent: name, min: 1)
            try self.validate(self.note, name: "note", parent: name, pattern: "^[.\\s\\S]*$")
            try self.validate(self.pageId, name: "pageId", parent: name, max: 2048)
            try self.validate(self.pageId, name: "pageId", parent: name, min: 1)
            try self.validate(self.pageId, name: "pageId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case acceptCode = "AcceptCode"
            case acceptCodeValidation = "AcceptCodeValidation"
            case acceptType = "AcceptType"
            case contactChannelId = "ContactChannelId"
            case note = "Note"
            case pageId = "PageId"
        }
    }

    public struct AcceptPageResult: AWSDecodableShape {
        public init() {}
    }

    public struct ActivateContactChannelRequest: AWSEncodableShape {
        /// The code sent to the contact channel when it was created in the contact.
        public let activationCode: String
        /// The Amazon Resource Name (ARN) of the contact channel.
        public let contactChannelId: String

        public init(activationCode: String, contactChannelId: String) {
            self.activationCode = activationCode
            self.contactChannelId = contactChannelId
        }

        public func validate(name: String) throws {
            try self.validate(self.activationCode, name: "activationCode", parent: name, max: 10)
            try self.validate(self.activationCode, name: "activationCode", parent: name, min: 6)
            try self.validate(self.activationCode, name: "activationCode", parent: name, pattern: "^[0-9]*$")
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case activationCode = "ActivationCode"
            case contactChannelId = "ContactChannelId"
        }
    }

    public struct ActivateContactChannelResult: AWSDecodableShape {
        public init() {}
    }

    public struct ChannelTargetInfo: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel.
        public let contactChannelId: String
        /// The number of minutes to wait to retry sending engagement in the case the engagement initially fails.
        public let retryIntervalInMinutes: Int?

        public init(contactChannelId: String, retryIntervalInMinutes: Int? = nil) {
            self.contactChannelId = contactChannelId
            self.retryIntervalInMinutes = retryIntervalInMinutes
        }

        public func validate(name: String) throws {
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.retryIntervalInMinutes, name: "retryIntervalInMinutes", parent: name, max: 60)
            try self.validate(self.retryIntervalInMinutes, name: "retryIntervalInMinutes", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelId = "ContactChannelId"
            case retryIntervalInMinutes = "RetryIntervalInMinutes"
        }
    }

    public struct Contact: AWSDecodableShape {
        /// The unique and identifiable alias of the contact or escalation plan.
        public let alias: String
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let contactArn: String
        /// The full name of the contact or escalation plan.
        public let displayName: String?
        /// Refers to the type of contact. A single contact is type PERSONAL and an escalation plan is type ESCALATION.
        public let type: ContactType

        public init(alias: String, contactArn: String, displayName: String? = nil, type: ContactType) {
            self.alias = alias
            self.contactArn = contactArn
            self.displayName = displayName
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case alias = "Alias"
            case contactArn = "ContactArn"
            case displayName = "DisplayName"
            case type = "Type"
        }
    }

    public struct ContactChannel: AWSDecodableShape {
        /// A Boolean value describing if the contact channel has been activated or not. If the contact channel isn't activated, Incident Manager can't engage the contact through it.
        public let activationStatus: ActivationStatus
        /// The ARN of the contact that contains the contact channel.
        public let contactArn: String
        /// The Amazon Resource Name (ARN) of the contact channel.
        public let contactChannelArn: String
        /// The details that Incident Manager uses when trying to engage the contact channel.
        public let deliveryAddress: ContactChannelAddress
        /// The name of the contact channel.
        public let name: String
        /// The type of the contact channel. Incident Manager supports three contact methods:   SMS   VOICE   EMAIL
        public let type: ChannelType?

        public init(activationStatus: ActivationStatus, contactArn: String, contactChannelArn: String, deliveryAddress: ContactChannelAddress, name: String, type: ChannelType? = nil) {
            self.activationStatus = activationStatus
            self.contactArn = contactArn
            self.contactChannelArn = contactChannelArn
            self.deliveryAddress = deliveryAddress
            self.name = name
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case activationStatus = "ActivationStatus"
            case contactArn = "ContactArn"
            case contactChannelArn = "ContactChannelArn"
            case deliveryAddress = "DeliveryAddress"
            case name = "Name"
            case type = "Type"
        }
    }

    public struct ContactChannelAddress: AWSEncodableShape & AWSDecodableShape {
        /// The format is dependent on the type of the contact channel. The following are the expected formats:   SMS - '+' followed by the country code and phone number   VOICE - '+' followed by the country code and phone number   EMAIL - any standard email format
        public let simpleAddress: String?

        public init(simpleAddress: String? = nil) {
            self.simpleAddress = simpleAddress
        }

        public func validate(name: String) throws {
            try self.validate(self.simpleAddress, name: "simpleAddress", parent: name, max: 320)
            try self.validate(self.simpleAddress, name: "simpleAddress", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case simpleAddress = "SimpleAddress"
        }
    }

    public struct ContactTargetInfo: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the contact.
        public let contactId: String?
        /// A Boolean value determining if the contact's acknowledgement stops the progress of stages in the plan.
        public let isEssential: Bool

        public init(contactId: String? = nil, isEssential: Bool) {
            self.contactId = contactId
            self.isEssential = isEssential
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
            case isEssential = "IsEssential"
        }
    }

    public struct CreateContactChannelRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact you are adding the contact channel to.
        public let contactId: String
        /// If you want to activate the channel at a later time, you can choose to defer activation. Incident Manager can't engage your contact channel until it has been activated.
        public let deferActivation: Bool?
        /// The details that Incident Manager uses when trying to engage the contact channel. The format is dependent on the type of the contact channel. The following are the expected formats:   SMS - '+' followed by the country code and phone number   VOICE - '+' followed by the country code and phone number   EMAIL - any standard email format
        public let deliveryAddress: ContactChannelAddress
        /// A token ensuring that the operation is called only once with the specified details.
        public let idempotencyToken: String?
        /// The name of the contact channel.
        public let name: String
        /// Incident Manager supports three types of contact channels:    SMS     VOICE     EMAIL
        public let type: ChannelType

        public init(contactId: String, deferActivation: Bool? = nil, deliveryAddress: ContactChannelAddress, idempotencyToken: String? = CreateContactChannelRequest.idempotencyToken(), name: String, type: ChannelType) {
            self.contactId = contactId
            self.deferActivation = deferActivation
            self.deliveryAddress = deliveryAddress
            self.idempotencyToken = idempotencyToken
            self.name = name
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.deliveryAddress.validate(name: "\(name).deliveryAddress")
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, max: 2048)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
            case deferActivation = "DeferActivation"
            case deliveryAddress = "DeliveryAddress"
            case idempotencyToken = "IdempotencyToken"
            case name = "Name"
            case type = "Type"
        }
    }

    public struct CreateContactChannelResult: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel.
        public let contactChannelArn: String

        public init(contactChannelArn: String) {
            self.contactChannelArn = contactChannelArn
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelArn = "ContactChannelArn"
        }
    }

    public struct CreateContactRequest: AWSEncodableShape {
        /// The short name to quickly identify a contact or escalation plan. The contact alias must be unique and identifiable.
        public let alias: String
        /// The full name of the contact or escalation plan.
        public let displayName: String?
        /// A token ensuring that the operation is called only once with the specified details.
        public let idempotencyToken: String?
        /// A list of stages. A contact has an engagement plan with stages that contact specified contact channels. An escalation plan uses stages that contact specified contacts.
        public let plan: Plan
        /// Adds a tag to the target. You can only tag resources created in the first Region of your replication set.
        public let tags: [Tag]?
        /// To create an escalation plan use ESCALATION. To create a contact use PERSONAL.
        public let type: ContactType

        public init(alias: String, displayName: String? = nil, idempotencyToken: String? = CreateContactRequest.idempotencyToken(), plan: Plan, tags: [Tag]? = nil, type: ContactType) {
            self.alias = alias
            self.displayName = displayName
            self.idempotencyToken = idempotencyToken
            self.plan = plan
            self.tags = tags
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.alias, name: "alias", parent: name, max: 255)
            try self.validate(self.alias, name: "alias", parent: name, min: 1)
            try self.validate(self.alias, name: "alias", parent: name, pattern: "^[a-z0-9_\\-]*$")
            try self.validate(self.displayName, name: "displayName", parent: name, max: 255)
            try self.validate(self.displayName, name: "displayName", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.\\-]*$")
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, max: 2048)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
            try self.plan.validate(name: "\(name).plan")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case alias = "Alias"
            case displayName = "DisplayName"
            case idempotencyToken = "IdempotencyToken"
            case plan = "Plan"
            case tags = "Tags"
            case type = "Type"
        }
    }

    public struct CreateContactResult: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the created contact or escalation plan.
        public let contactArn: String

        public init(contactArn: String) {
            self.contactArn = contactArn
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
        }
    }

    public struct DeactivateContactChannelRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel you're deactivating.
        public let contactChannelId: String

        public init(contactChannelId: String) {
            self.contactChannelId = contactChannelId
        }

        public func validate(name: String) throws {
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelId = "ContactChannelId"
        }
    }

    public struct DeactivateContactChannelResult: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteContactChannelRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel.
        public let contactChannelId: String

        public init(contactChannelId: String) {
            self.contactChannelId = contactChannelId
        }

        public func validate(name: String) throws {
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelId = "ContactChannelId"
        }
    }

    public struct DeleteContactChannelResult: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteContactRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact that you're deleting.
        public let contactId: String

        public init(contactId: String) {
            self.contactId = contactId
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
        }
    }

    public struct DeleteContactResult: AWSDecodableShape {
        public init() {}
    }

    public struct DescribeEngagementRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the engagement you want the details of.
        public let engagementId: String

        public init(engagementId: String) {
            self.engagementId = engagementId
        }

        public func validate(name: String) throws {
            try self.validate(self.engagementId, name: "engagementId", parent: name, max: 2048)
            try self.validate(self.engagementId, name: "engagementId", parent: name, min: 1)
            try self.validate(self.engagementId, name: "engagementId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case engagementId = "EngagementId"
        }
    }

    public struct DescribeEngagementResult: AWSDecodableShape {
        /// The ARN of the escalation plan or contacts involved in the engagement.
        public let contactArn: String
        /// The secure content of the message that was sent to the contact. Use this field for engagements to VOICE and EMAIL.
        public let content: String
        /// The ARN of the engagement.
        public let engagementArn: String
        /// The ARN of the incident in which the engagement occurred.
        public let incidentId: String?
        /// The insecure content of the message that was sent to the contact. Use this field for engagements to SMS.
        public let publicContent: String?
        /// The insecure subject of the message that was sent to the contact. Use this field for engagements to SMS.
        public let publicSubject: String?
        /// The user that started the engagement.
        public let sender: String
        /// The time that the engagement started.
        public let startTime: Date?
        /// The time that the engagement ended.
        public let stopTime: Date?
        /// The secure subject of the message that was sent to the contact. Use this field for engagements to VOICE and EMAIL.
        public let subject: String

        public init(contactArn: String, content: String, engagementArn: String, incidentId: String? = nil, publicContent: String? = nil, publicSubject: String? = nil, sender: String, startTime: Date? = nil, stopTime: Date? = nil, subject: String) {
            self.contactArn = contactArn
            self.content = content
            self.engagementArn = engagementArn
            self.incidentId = incidentId
            self.publicContent = publicContent
            self.publicSubject = publicSubject
            self.sender = sender
            self.startTime = startTime
            self.stopTime = stopTime
            self.subject = subject
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
            case content = "Content"
            case engagementArn = "EngagementArn"
            case incidentId = "IncidentId"
            case publicContent = "PublicContent"
            case publicSubject = "PublicSubject"
            case sender = "Sender"
            case startTime = "StartTime"
            case stopTime = "StopTime"
            case subject = "Subject"
        }
    }

    public struct DescribePageRequest: AWSEncodableShape {
        /// The ID of the engagement to a contact channel.
        public let pageId: String

        public init(pageId: String) {
            self.pageId = pageId
        }

        public func validate(name: String) throws {
            try self.validate(self.pageId, name: "pageId", parent: name, max: 2048)
            try self.validate(self.pageId, name: "pageId", parent: name, min: 1)
            try self.validate(self.pageId, name: "pageId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case pageId = "PageId"
        }
    }

    public struct DescribePageResult: AWSDecodableShape {
        /// The ARN of the contact that was engaged.
        public let contactArn: String
        /// The secure content of the message that was sent to the contact. Use this field for engagements to VOICE and EMAIL.
        public let content: String
        /// The time that the contact channel received the engagement.
        public let deliveryTime: Date?
        /// The ARN of the engagement that engaged the contact channel.
        public let engagementArn: String
        /// The ARN of the incident that engaged the contact channel.
        public let incidentId: String?
        /// The Amazon Resource Name (ARN) of the engagement to a contact channel.
        public let pageArn: String
        /// The insecure content of the message that was sent to the contact. Use this field for engagements to SMS.
        public let publicContent: String?
        /// The insecure subject of the message that was sent to the contact. Use this field for engagements to SMS.
        public let publicSubject: String?
        /// The time that the contact channel acknowledged the engagement.
        public let readTime: Date?
        /// The user that started the engagement.
        public let sender: String
        /// The time the engagement was sent to the contact channel.
        public let sentTime: Date?
        /// The secure subject of the message that was sent to the contact. Use this field for engagements to VOICE and EMAIL.
        public let subject: String

        public init(contactArn: String, content: String, deliveryTime: Date? = nil, engagementArn: String, incidentId: String? = nil, pageArn: String, publicContent: String? = nil, publicSubject: String? = nil, readTime: Date? = nil, sender: String, sentTime: Date? = nil, subject: String) {
            self.contactArn = contactArn
            self.content = content
            self.deliveryTime = deliveryTime
            self.engagementArn = engagementArn
            self.incidentId = incidentId
            self.pageArn = pageArn
            self.publicContent = publicContent
            self.publicSubject = publicSubject
            self.readTime = readTime
            self.sender = sender
            self.sentTime = sentTime
            self.subject = subject
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
            case content = "Content"
            case deliveryTime = "DeliveryTime"
            case engagementArn = "EngagementArn"
            case incidentId = "IncidentId"
            case pageArn = "PageArn"
            case publicContent = "PublicContent"
            case publicSubject = "PublicSubject"
            case readTime = "ReadTime"
            case sender = "Sender"
            case sentTime = "SentTime"
            case subject = "Subject"
        }
    }

    public struct Engagement: AWSDecodableShape {
        /// The ARN of the escalation plan or contact that Incident Manager is engaging.
        public let contactArn: String
        /// The Amazon Resource Name (ARN) of the engagement.
        public let engagementArn: String
        /// The ARN of the incident that's engaging the contact.
        public let incidentId: String?
        /// The user that started the engagement.
        public let sender: String
        /// The time that the engagement began.
        public let startTime: Date?
        /// The time that the engagement ended.
        public let stopTime: Date?

        public init(contactArn: String, engagementArn: String, incidentId: String? = nil, sender: String, startTime: Date? = nil, stopTime: Date? = nil) {
            self.contactArn = contactArn
            self.engagementArn = engagementArn
            self.incidentId = incidentId
            self.sender = sender
            self.startTime = startTime
            self.stopTime = stopTime
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
            case engagementArn = "EngagementArn"
            case incidentId = "IncidentId"
            case sender = "Sender"
            case startTime = "StartTime"
            case stopTime = "StopTime"
        }
    }

    public struct GetContactChannelRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel you want information about.
        public let contactChannelId: String

        public init(contactChannelId: String) {
            self.contactChannelId = contactChannelId
        }

        public func validate(name: String) throws {
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelId = "ContactChannelId"
        }
    }

    public struct GetContactChannelResult: AWSDecodableShape {
        /// A Boolean value indicating if the contact channel has been activated or not.
        public let activationStatus: ActivationStatus?
        /// The ARN of the contact that the channel belongs to.
        public let contactArn: String
        /// The ARN of the contact channel.
        public let contactChannelArn: String
        /// The details that Incident Manager uses when trying to engage the contact channel.
        public let deliveryAddress: ContactChannelAddress
        /// The name of the contact channel
        public let name: String
        /// The type of contact channel. The type is SMS, VOICE, or EMAIL.
        public let type: ChannelType

        public init(activationStatus: ActivationStatus? = nil, contactArn: String, contactChannelArn: String, deliveryAddress: ContactChannelAddress, name: String, type: ChannelType) {
            self.activationStatus = activationStatus
            self.contactArn = contactArn
            self.contactChannelArn = contactChannelArn
            self.deliveryAddress = deliveryAddress
            self.name = name
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case activationStatus = "ActivationStatus"
            case contactArn = "ContactArn"
            case contactChannelArn = "ContactChannelArn"
            case deliveryAddress = "DeliveryAddress"
            case name = "Name"
            case type = "Type"
        }
    }

    public struct GetContactPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let contactArn: String

        public init(contactArn: String) {
            self.contactArn = contactArn
        }

        public func validate(name: String) throws {
            try self.validate(self.contactArn, name: "contactArn", parent: name, max: 2048)
            try self.validate(self.contactArn, name: "contactArn", parent: name, min: 1)
            try self.validate(self.contactArn, name: "contactArn", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
        }
    }

    public struct GetContactPolicyResult: AWSDecodableShape {
        /// The ARN of the contact or escalation plan.
        public let contactArn: String?
        /// Details about the resource policy attached to the contact or escalation plan.
        public let policy: String?

        public init(contactArn: String? = nil, policy: String? = nil) {
            self.contactArn = contactArn
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
            case policy = "Policy"
        }
    }

    public struct GetContactRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let contactId: String

        public init(contactId: String) {
            self.contactId = contactId
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
        }
    }

    public struct GetContactResult: AWSDecodableShape {
        /// The alias of the contact or escalation plan. The alias is unique and identifiable.
        public let alias: String
        /// The ARN of the contact or escalation plan.
        public let contactArn: String
        /// The full name of the contact or escalation plan.
        public let displayName: String?
        /// Details about the specific timing or stages and targets of the escalation plan or engagement plan.
        public let plan: Plan
        /// The type of contact, either PERSONAL or ESCALATION.
        public let type: ContactType

        public init(alias: String, contactArn: String, displayName: String? = nil, plan: Plan, type: ContactType) {
            self.alias = alias
            self.contactArn = contactArn
            self.displayName = displayName
            self.plan = plan
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case alias = "Alias"
            case contactArn = "ContactArn"
            case displayName = "DisplayName"
            case plan = "Plan"
            case type = "Type"
        }
    }

    public struct ListContactChannelsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact.
        public let contactId: String
        /// The maximum number of contact channels per page.
        public let maxResults: Int?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?

        public init(contactId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.contactId = contactId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1024)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListContactChannelsResult: AWSDecodableShape {
        /// A list of contact channels related to the specified contact.
        public let contactChannels: [ContactChannel]
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?

        public init(contactChannels: [ContactChannel], nextToken: String? = nil) {
            self.contactChannels = contactChannels
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannels = "ContactChannels"
            case nextToken = "NextToken"
        }
    }

    public struct ListContactsRequest: AWSEncodableShape {
        /// Used to list only contacts who's aliases start with the specified prefix.
        public let aliasPrefix: String?
        /// The maximum number of contacts and escalation plans per page of results.
        public let maxResults: Int?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?
        /// The type of contact. A contact is type PERSONAL and an escalation plan is type ESCALATION.
        public let type: ContactType?

        public init(aliasPrefix: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, type: ContactType? = nil) {
            self.aliasPrefix = aliasPrefix
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.aliasPrefix, name: "aliasPrefix", parent: name, max: 255)
            try self.validate(self.aliasPrefix, name: "aliasPrefix", parent: name, min: 1)
            try self.validate(self.aliasPrefix, name: "aliasPrefix", parent: name, pattern: "^[a-z0-9_\\-]*$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1024)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case aliasPrefix = "AliasPrefix"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case type = "Type"
        }
    }

    public struct ListContactsResult: AWSDecodableShape {
        /// A list of the contacts and escalation plans in your Incident Manager account.
        public let contacts: [Contact]?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?

        public init(contacts: [Contact]? = nil, nextToken: String? = nil) {
            self.contacts = contacts
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case contacts = "Contacts"
            case nextToken = "NextToken"
        }
    }

    public struct ListEngagementsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the incident you're listing engagements for.
        public let incidentId: String?
        /// The maximum number of engagements per page of results.
        public let maxResults: Int?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?
        /// The time range to lists engagements for an incident.
        public let timeRangeValue: TimeRange?

        public init(incidentId: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, timeRangeValue: TimeRange? = nil) {
            self.incidentId = incidentId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.timeRangeValue = timeRangeValue
        }

        public func validate(name: String) throws {
            try self.validate(self.incidentId, name: "incidentId", parent: name, max: 1024)
            try self.validate(self.incidentId, name: "incidentId", parent: name, pattern: "^[\\\\a-zA-Z0-9_@#%*+=:?.\\/!\\s-]*$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1024)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case incidentId = "IncidentId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case timeRangeValue = "TimeRangeValue"
        }
    }

    public struct ListEngagementsResult: AWSDecodableShape {
        /// A list of each engagement that occurred during the specified time range of an incident.
        public let engagements: [Engagement]
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?

        public init(engagements: [Engagement], nextToken: String? = nil) {
            self.engagements = engagements
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case engagements = "Engagements"
            case nextToken = "NextToken"
        }
    }

    public struct ListPageReceiptsRequest: AWSEncodableShape {
        /// The maximum number of acknowledgements per page of results.
        public let maxResults: Int?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the engagement to a specific contact channel.
        public let pageId: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, pageId: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.pageId = pageId
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1024)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
            try self.validate(self.pageId, name: "pageId", parent: name, max: 2048)
            try self.validate(self.pageId, name: "pageId", parent: name, min: 1)
            try self.validate(self.pageId, name: "pageId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case pageId = "PageId"
        }
    }

    public struct ListPageReceiptsResult: AWSDecodableShape {
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?
        /// A list of each acknowledgement.
        public let receipts: [Receipt]?

        public init(nextToken: String? = nil, receipts: [Receipt]? = nil) {
            self.nextToken = nextToken
            self.receipts = receipts
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case receipts = "Receipts"
        }
    }

    public struct ListPagesByContactRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact you are retrieving engagements for.
        public let contactId: String
        /// The maximum number of engagements to contact channels to list per page of results.
        public let maxResults: Int?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?

        public init(contactId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.contactId = contactId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1024)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListPagesByContactResult: AWSDecodableShape {
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?
        /// The list of engagements to a contact's contact channel.
        public let pages: [Page]

        public init(nextToken: String? = nil, pages: [Page]) {
            self.nextToken = nextToken
            self.pages = pages
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case pages = "Pages"
        }
    }

    public struct ListPagesByEngagementRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the engagement.
        public let engagementId: String
        /// The maximum number of engagements to contact channels to list per page of results.
        public let maxResults: Int?
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?

        public init(engagementId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.engagementId = engagementId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.engagementId, name: "engagementId", parent: name, max: 2048)
            try self.validate(self.engagementId, name: "engagementId", parent: name, min: 1)
            try self.validate(self.engagementId, name: "engagementId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1024)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case engagementId = "EngagementId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListPagesByEngagementResult: AWSDecodableShape {
        /// The pagination token to continue to the next page of results.
        public let nextToken: String?
        /// The list of engagements to contact channels.
        public let pages: [Page]

        public init(nextToken: String? = nil, pages: [Page]) {
            self.nextToken = nextToken
            self.pages = pages
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case pages = "Pages"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let resourceARN: String

        public init(resourceARN: String) {
            self.resourceARN = resourceARN
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1011)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
        }
    }

    public struct ListTagsForResourceResult: AWSDecodableShape {
        /// The tags related to the contact or escalation plan.
        public let tags: [Tag]?

        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct Page: AWSDecodableShape {
        /// The ARN of the contact that Incident Manager is engaging.
        public let contactArn: String
        /// The time the message was delivered to the contact channel.
        public let deliveryTime: Date?
        /// The ARN of the engagement that this page is part of.
        public let engagementArn: String
        /// The ARN of the incident that's engaging the contact channel.
        public let incidentId: String?
        /// The Amazon Resource Name (ARN) of the page to the contact channel.
        public let pageArn: String
        /// The time that the contact channel acknowledged engagement.
        public let readTime: Date?
        /// The user that started the engagement.
        public let sender: String
        /// The time that Incident Manager engaged the contact channel.
        public let sentTime: Date?

        public init(contactArn: String, deliveryTime: Date? = nil, engagementArn: String, incidentId: String? = nil, pageArn: String, readTime: Date? = nil, sender: String, sentTime: Date? = nil) {
            self.contactArn = contactArn
            self.deliveryTime = deliveryTime
            self.engagementArn = engagementArn
            self.incidentId = incidentId
            self.pageArn = pageArn
            self.readTime = readTime
            self.sender = sender
            self.sentTime = sentTime
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
            case deliveryTime = "DeliveryTime"
            case engagementArn = "EngagementArn"
            case incidentId = "IncidentId"
            case pageArn = "PageArn"
            case readTime = "ReadTime"
            case sender = "Sender"
            case sentTime = "SentTime"
        }
    }

    public struct Plan: AWSEncodableShape & AWSDecodableShape {
        /// A list of stages that the escalation plan or engagement plan uses to engage contacts and contact methods.
        public let stages: [Stage]

        public init(stages: [Stage]) {
            self.stages = stages
        }

        public func validate(name: String) throws {
            try self.stages.forEach {
                try $0.validate(name: "\(name).stages[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case stages = "Stages"
        }
    }

    public struct PutContactPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let contactArn: String
        /// Details of the resource policy.
        public let policy: String

        public init(contactArn: String, policy: String) {
            self.contactArn = contactArn
            self.policy = policy
        }

        public func validate(name: String) throws {
            try self.validate(self.contactArn, name: "contactArn", parent: name, max: 2048)
            try self.validate(self.contactArn, name: "contactArn", parent: name, min: 1)
            try self.validate(self.contactArn, name: "contactArn", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.policy, name: "policy", parent: name, max: 395_000)
            try self.validate(self.policy, name: "policy", parent: name, min: 1)
            try self.validate(self.policy, name: "policy", parent: name, pattern: "\\S")
        }

        private enum CodingKeys: String, CodingKey {
            case contactArn = "ContactArn"
            case policy = "Policy"
        }
    }

    public struct PutContactPolicyResult: AWSDecodableShape {
        public init() {}
    }

    public struct Receipt: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel Incident Manager engaged.
        public let contactChannelArn: String?
        /// Information provided during the page acknowledgement.
        public let receiptInfo: String?
        /// The time receipt was SENT, DELIVERED, or READ.
        public let receiptTime: Date
        /// The type follows the engagement cycle, SENT, DELIVERED, and READ.
        public let receiptType: ReceiptType

        public init(contactChannelArn: String? = nil, receiptInfo: String? = nil, receiptTime: Date, receiptType: ReceiptType) {
            self.contactChannelArn = contactChannelArn
            self.receiptInfo = receiptInfo
            self.receiptTime = receiptTime
            self.receiptType = receiptType
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelArn = "ContactChannelArn"
            case receiptInfo = "ReceiptInfo"
            case receiptTime = "ReceiptTime"
            case receiptType = "ReceiptType"
        }
    }

    public struct SendActivationCodeRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel.
        public let contactChannelId: String

        public init(contactChannelId: String) {
            self.contactChannelId = contactChannelId
        }

        public func validate(name: String) throws {
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelId = "ContactChannelId"
        }
    }

    public struct SendActivationCodeResult: AWSDecodableShape {
        public init() {}
    }

    public struct Stage: AWSEncodableShape & AWSDecodableShape {
        /// The time to wait until beginning the next stage. The duration can only be set to 0 if a target is specified.
        public let durationInMinutes: Int
        /// The contacts or contact methods that the escalation plan or engagement plan is engaging.
        public let targets: [Target]

        public init(durationInMinutes: Int, targets: [Target]) {
            self.durationInMinutes = durationInMinutes
            self.targets = targets
        }

        public func validate(name: String) throws {
            try self.validate(self.durationInMinutes, name: "durationInMinutes", parent: name, max: 30)
            try self.validate(self.durationInMinutes, name: "durationInMinutes", parent: name, min: 0)
            try self.targets.forEach {
                try $0.validate(name: "\(name).targets[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case durationInMinutes = "DurationInMinutes"
            case targets = "Targets"
        }
    }

    public struct StartEngagementRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact being engaged.
        public let contactId: String
        /// The secure content of the message that was sent to the contact. Use this field for engagements to VOICE or EMAIL.
        public let content: String
        /// A token ensuring that the operation is called only once with the specified details.
        public let idempotencyToken: String?
        /// The ARN of the incident that the engagement is part of.
        public let incidentId: String?
        /// The insecure content of the message that was sent to the contact. Use this field for engagements to SMS.
        public let publicContent: String?
        /// The insecure subject of the message that was sent to the contact. Use this field for engagements to SMS.
        public let publicSubject: String?
        /// The user that started the engagement.
        public let sender: String
        /// The secure subject of the message that was sent to the contact. Use this field for engagements to VOICE or EMAIL.
        public let subject: String

        public init(contactId: String, content: String, idempotencyToken: String? = StartEngagementRequest.idempotencyToken(), incidentId: String? = nil, publicContent: String? = nil, publicSubject: String? = nil, sender: String, subject: String) {
            self.contactId = contactId
            self.content = content
            self.idempotencyToken = idempotencyToken
            self.incidentId = incidentId
            self.publicContent = publicContent
            self.publicSubject = publicSubject
            self.sender = sender
            self.subject = subject
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.content, name: "content", parent: name, max: 8192)
            try self.validate(self.content, name: "content", parent: name, min: 1)
            try self.validate(self.content, name: "content", parent: name, pattern: "^[.\\s\\S]*$")
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, max: 2048)
            try self.validate(self.idempotencyToken, name: "idempotencyToken", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
            try self.validate(self.incidentId, name: "incidentId", parent: name, max: 1024)
            try self.validate(self.incidentId, name: "incidentId", parent: name, pattern: "^[\\\\a-zA-Z0-9_@#%*+=:?.\\/!\\s-]*$")
            try self.validate(self.publicContent, name: "publicContent", parent: name, max: 8192)
            try self.validate(self.publicContent, name: "publicContent", parent: name, min: 1)
            try self.validate(self.publicContent, name: "publicContent", parent: name, pattern: "^[.\\s\\S]*$")
            try self.validate(self.publicSubject, name: "publicSubject", parent: name, max: 2048)
            try self.validate(self.publicSubject, name: "publicSubject", parent: name, min: 1)
            try self.validate(self.publicSubject, name: "publicSubject", parent: name, pattern: "^[.\\s\\S]*$")
            try self.validate(self.sender, name: "sender", parent: name, max: 255)
            try self.validate(self.sender, name: "sender", parent: name, pattern: "^[\\\\a-zA-Z0-9_@#%*+=:?.\\/!\\s-]*$")
            try self.validate(self.subject, name: "subject", parent: name, max: 2048)
            try self.validate(self.subject, name: "subject", parent: name, min: 1)
            try self.validate(self.subject, name: "subject", parent: name, pattern: "^[.\\s\\S]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
            case content = "Content"
            case idempotencyToken = "IdempotencyToken"
            case incidentId = "IncidentId"
            case publicContent = "PublicContent"
            case publicSubject = "PublicSubject"
            case sender = "Sender"
            case subject = "Subject"
        }
    }

    public struct StartEngagementResult: AWSDecodableShape {
        /// The ARN of the engagement.
        public let engagementArn: String

        public init(engagementArn: String) {
            self.engagementArn = engagementArn
        }

        private enum CodingKeys: String, CodingKey {
            case engagementArn = "EngagementArn"
        }
    }

    public struct StopEngagementRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the engagement.
        public let engagementId: String
        /// The reason that you're stopping the engagement.
        public let reason: String?

        public init(engagementId: String, reason: String? = nil) {
            self.engagementId = engagementId
            self.reason = reason
        }

        public func validate(name: String) throws {
            try self.validate(self.engagementId, name: "engagementId", parent: name, max: 2048)
            try self.validate(self.engagementId, name: "engagementId", parent: name, min: 1)
            try self.validate(self.engagementId, name: "engagementId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.reason, name: "reason", parent: name, max: 255)
            try self.validate(self.reason, name: "reason", parent: name, pattern: "^[.\\s\\S]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case engagementId = "EngagementId"
            case reason = "Reason"
        }
    }

    public struct StopEngagementResult: AWSDecodableShape {
        public init() {}
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// Name of the object key.
        public let key: String?
        /// Value of the tag.
        public let value: String?

        public init(key: String? = nil, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.:\\/=+\\-@]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let resourceARN: String
        /// A list of tags that you are adding to the contact or escalation plan.
        public let tags: [Tag]

        public init(resourceARN: String, tags: [Tag]) {
            self.resourceARN = resourceARN
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1011)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tags = "Tags"
        }
    }

    public struct TagResourceResult: AWSDecodableShape {
        public init() {}
    }

    public struct Target: AWSEncodableShape & AWSDecodableShape {
        /// Information about the contact channel Incident Manager is engaging.
        public let channelTargetInfo: ChannelTargetInfo?
        /// Information about the contact that Incident Manager is engaging.
        public let contactTargetInfo: ContactTargetInfo?

        public init(channelTargetInfo: ChannelTargetInfo? = nil, contactTargetInfo: ContactTargetInfo? = nil) {
            self.channelTargetInfo = channelTargetInfo
            self.contactTargetInfo = contactTargetInfo
        }

        public func validate(name: String) throws {
            try self.channelTargetInfo?.validate(name: "\(name).channelTargetInfo")
            try self.contactTargetInfo?.validate(name: "\(name).contactTargetInfo")
        }

        private enum CodingKeys: String, CodingKey {
            case channelTargetInfo = "ChannelTargetInfo"
            case contactTargetInfo = "ContactTargetInfo"
        }
    }

    public struct TimeRange: AWSEncodableShape {
        /// The end of the time range.
        public let endTime: Date?
        /// The start of the time range.
        public let startTime: Date?

        public init(endTime: Date? = nil, startTime: Date? = nil) {
            self.endTime = endTime
            self.startTime = startTime
        }

        private enum CodingKeys: String, CodingKey {
            case endTime = "EndTime"
            case startTime = "StartTime"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan.
        public let resourceARN: String
        /// The key of the tag that you want to remove.
        public let tagKeys: [String]

        public init(resourceARN: String, tagKeys: [String]) {
            self.resourceARN = resourceARN
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1011)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 1)
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^[\\\\\\/a-zA-Z0-9_+=\\-]*$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResult: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateContactChannelRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact channel you want to update.
        public let contactChannelId: String
        /// The details that Incident Manager uses when trying to engage the contact channel.
        public let deliveryAddress: ContactChannelAddress?
        /// The name of the contact channel.
        public let name: String?

        public init(contactChannelId: String, deliveryAddress: ContactChannelAddress? = nil, name: String? = nil) {
            self.contactChannelId = contactChannelId
            self.deliveryAddress = deliveryAddress
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, max: 2048)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, min: 1)
            try self.validate(self.contactChannelId, name: "contactChannelId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.deliveryAddress?.validate(name: "\(name).deliveryAddress")
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case contactChannelId = "ContactChannelId"
            case deliveryAddress = "DeliveryAddress"
            case name = "Name"
        }
    }

    public struct UpdateContactChannelResult: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateContactRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the contact or escalation plan you're updating.
        public let contactId: String
        /// The full name of the contact or escalation plan.
        public let displayName: String?
        /// A list of stages. A contact has an engagement plan with stages for specified contact channels. An escalation plan uses these stages to contact specified contacts.
        public let plan: Plan?

        public init(contactId: String, displayName: String? = nil, plan: Plan? = nil) {
            self.contactId = contactId
            self.displayName = displayName
            self.plan = plan
        }

        public func validate(name: String) throws {
            try self.validate(self.contactId, name: "contactId", parent: name, max: 2048)
            try self.validate(self.contactId, name: "contactId", parent: name, min: 1)
            try self.validate(self.contactId, name: "contactId", parent: name, pattern: "^arn:(aws|aws-cn|aws-us-gov):ssm-contacts:[-\\w+=\\/,.@]*:[0-9]+:([\\w+=\\/,.@:-]+)*$")
            try self.validate(self.displayName, name: "displayName", parent: name, max: 255)
            try self.validate(self.displayName, name: "displayName", parent: name, pattern: "^[\\p{L}\\p{Z}\\p{N}_.\\-]*$")
            try self.plan?.validate(name: "\(name).plan")
        }

        private enum CodingKeys: String, CodingKey {
            case contactId = "ContactId"
            case displayName = "DisplayName"
            case plan = "Plan"
        }
    }

    public struct UpdateContactResult: AWSDecodableShape {
        public init() {}
    }
}

// MARK: - Errors

/// Error enum for SSMContacts
public struct SSMContactsErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case dataEncryptionException = "DataEncryptionException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize SSMContacts
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You don&#39;t have sufficient access to perform this operation.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// Updating or deleting a resource causes an inconsistent state.
    public static var conflictException: Self { .init(.conflictException) }
    /// The operation failed to due an encryption key error.
    public static var dataEncryptionException: Self { .init(.dataEncryptionException) }
    /// Unexpected error occurred while processing the request.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// Request references a resource that doesn&#39;t exist.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Request would cause a service quota to be exceeded.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The input fails to satisfy the constraints specified by an Amazon Web Services service.
    public static var validationException: Self { .init(.validationException) }
}

extension SSMContactsErrorType: Equatable {
    public static func == (lhs: SSMContactsErrorType, rhs: SSMContactsErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension SSMContactsErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
